/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main.LanguageResource.LanguageIndependent.POSTagger;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import main.LanguageResource.DefaultWordConstruct;
import main.LanguageResource.LocalPOSFactory;
import main.LanguageResource.POS_Tagger;
import main.LanguageResource.WordConstruct;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSTagger;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.sentdetect.SentenceDetector;
import opennlp.tools.sentdetect.SentenceDetectorME;
import opennlp.tools.sentdetect.SentenceModel;
import opennlp.tools.tokenize.Tokenizer;
import opennlp.tools.tokenize.TokenizerME;
import opennlp.tools.tokenize.TokenizerModel;

/**
 *
 * @author Isaac Osesina
 */
public class OpenNLPMain<E> implements POS_Tagger<E>{

    private static OpenNLPMain singleton;
    private static SentenceDetector _sentenceDetector = null;
    private static Tokenizer _tokenizer = null;
    private static POSTagger _posTagger = null;
    


    private OpenNLPMain(String sentenceModelFilePath, String tokenModelFilePath, String POSModelFilePath) {
        createSentenceDetector(sentenceModelFilePath);
        createTokenizer(tokenModelFilePath);
        createPOSTagger(POSModelFilePath);
    }

    public static OpenNLPMain getSingleton(String sentenceModelFilePath, String tokenModelFilePath, String POSModelFilePath) {
        if (singleton == null) {
            singleton = new OpenNLPMain(sentenceModelFilePath, tokenModelFilePath, POSModelFilePath);
        }
        return singleton;
    }

    private void createSentenceDetector(String sentenceModelFilePath) {

        InputStream modelIn = null;
        try {
            // Loading sentence detection model
            modelIn = new FileInputStream(sentenceModelFilePath);    //"/en-sent.bin"
            final SentenceModel sentenceModel = new SentenceModel(modelIn);
            modelIn.close();

            _sentenceDetector = new SentenceDetectorME(sentenceModel);

        } catch (final IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (modelIn != null) {
                try {
                    modelIn.close();
                } catch (final IOException e) {
                } // oh well!
            }
        }
    }

    private void createTokenizer(String tokenModelFilePath) {

        InputStream modelIn = null;
        try {
            // Loading tokenizer model
            modelIn = new FileInputStream(tokenModelFilePath);   //"/en-token.bin"
            final TokenizerModel tokenModel = new TokenizerModel(modelIn);
            modelIn.close();

            _tokenizer = new TokenizerME(tokenModel);

        } catch (final IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (modelIn != null) {
                try {
                    modelIn.close();
                } catch (final IOException e) {
                } // oh well!
            }
        }
    }

    private void createPOSTagger(String POSModelFilePath) {

        InputStream modelIn = null;
        try {
            // Loading tokenizer model
            modelIn = new FileInputStream(POSModelFilePath); //"/en-pos-maxent.bin"
            final POSModel posModel = new POSModel(modelIn);
            modelIn.close();

            _posTagger = new POSTaggerME(posModel);

        } catch (final IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (modelIn != null) {
                try {
                    modelIn.close();
                } catch (final IOException e) {
                } // oh well!
            }
        }
    }

    public static POSTagger getPosTagger() {
        return _posTagger;
    }

    public static SentenceDetector getSentenceDetector() {
        return _sentenceDetector;
    }

    public static Tokenizer getTokenizer() {
        return _tokenizer;
    }
    
    
    @Override
    public String[] tokenize(String phrase) {
        if(_tokenizer==null || phrase == null)
            return null;
        return _tokenizer.tokenize(phrase);
    }
    

    @Override
    public List<WordConstruct<E>> tagPOS(LocalPOSFactory factory, String phrase) {
        if(_tokenizer==null || _posTagger == null || phrase == null)
            return null;
        String[] tokens = _tokenizer.tokenize(phrase);
        if(tokens==null)
            return null;
        String[] tags = _posTagger.tag(tokens);
        if(tags==null)
            return null;
        List<WordConstruct<E>> tagL = new ArrayList<WordConstruct<E>>();
        for(int i=0; i<tokens.length; i++){
            WordConstruct wc = new DefaultWordConstruct(factory,tokens[i]);
            wc.setPOS(tags[i]);
            tagL.add(wc);
        }
        return tagL;
    }
    
}
